#include "global.h"

#include <fcntl.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <unistd.h>

#include <fstream>
#include <thread>

#include "nlohmann/json.hpp"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h"

// 软件版本号
std::string APP_VERSION = "ZWHT-m400-gzxj-mxsf-V1.0_20250527";
// 模型版本号
std::string MODEL_VERSION = "0510_yvu";
// 云台版本号
std::string GIMBAL_VERSION = "M400-PTZ_V1.0_250527";

// 是否使用 12mm 镜头的标志
bool USE_12MM_LENS_FLAG = true;

// 是否开启不侦测区域
bool isDetectionAreaDisabled = false; 
// uint8_t zoom_change_count = 0;
// bool zoom_change_state = false;

char save_conf[8][30];
std::atomic<uint8_t> counter_action(0);

std::map<int, SpyConfig> load_spy_config(const std::string &filename)
{
    std::map<int, SpyConfig> spy_map;
    try
    {
        std::ifstream file(filename);
        if (!file.is_open())
        {
            std::cerr << "Failed to open " << filename << std::endl;
            return spy_map;
        }
        nlohmann::json jsonData;
        file >> jsonData;
        for (const auto &item : jsonData)
        {
            int id = item["id"];
            SpyConfig conf;
            conf.threshold = item["threshold"];
            conf.pan = item["pan"];
            conf.tilt = item["tilt"];
            conf.zoom = item["zoom"];
            spy_map[id] = conf;
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "Failed to load " << filename << ": " << e.what() << std::endl;
    }
    return spy_map;
}

bool save_spy_config(const std::string &filename, const std::map<int, SpyConfig> &spy_map)
{
    try
    {
        nlohmann::json jsonData;
        for (const auto &config : spy_map)
        {
            nlohmann::json item;
            item["id"] = config.first;
            item["threshold"] = config.second.threshold;
            item["pan"] = config.second.pan;
            item["tilt"] = config.second.tilt;
            item["zoom"] = config.second.zoom;
            jsonData.push_back(item);
        }
        std::ofstream file(filename);
        if (!file.is_open())
        {
            std::cerr << "Failed to open: " << filename << std::endl;
            return false;
        }
        file << jsonData.dump(4);  // 以缩进 4 个空格的格式写入
        return true;
    }
    catch (const std::exception &e)
    {
        std::cerr << "failed to save " << filename << ": " << e.what() << std::endl;
        return false;
    }
}

void custom_printf(const char *format, ...)
{
    // 获取当前时间
    auto now = std::chrono::system_clock::now();
    std::time_t current_time = std::chrono::system_clock::to_time_t(now);
    std::tm *local_time = std::localtime(&current_time);

    // 获取线程 ID
    std::thread::id thread_id = std::this_thread::get_id();

    // 获取毫秒部分
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;

    // 输出时间和线程 ID
    // std::cout << "[" << std::put_time(local_time, "%Y-%m-%d %H:%M:%S") << "."
    // << ms.count() << "] "; std::cout << "[Thread " << thread_id << "] ";

    // 处理可变参数
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    // 构造完整的日志消息
    std::ostringstream log_stream;
    log_stream << "[" << std::put_time(local_time, "%Y-%m-%d %H:%M:%S") << "." << std::setfill('0')
               << std::setw(3) << ms.count() << "] "
               << "[Thread " << thread_id << "] " << buffer;

    std::cout << log_stream.str() << std::endl;
}

// UUID 版本 4（随机生成），变体 RFC 4122
std::string generate_timestamp_id(int id)
{
    time_t now = time(nullptr);
    struct tm *local = localtime(&now);
    if (!local)
    {
        return std::to_string(id) + "_error";
    }

    char time_str[64] = {0};
    snprintf(time_str, sizeof(time_str), "%d%02d%02d%02d%02d%02d", local->tm_year + 1900,
             local->tm_mon + 1, local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec);

    return std::to_string(id) + "_" + time_str;
}
